package com.study.www.service;

import com.alibaba.fastjson.JSONObject;
import com.mongodb.client.FindIterable;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.model.Filters;
import com.study.www.config.*;
import com.study.www.entity.Dept;
import com.study.www.repository.DeptRepository;
import com.sun.jndi.toolkit.url.UrlUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.tomcat.util.codec.binary.Base64;
import org.bson.BsonDocument;
import org.bson.Document;
import org.bson.conversions.Bson;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.*;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Base64Utils;
import org.springframework.util.ObjectUtils;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.regex.Pattern;

/**
 * @author : Administrator.zhuyanpeng
 * @date : 2019/10/21 - 17:56
 */
@Service
@Slf4j
public class DeptTemplateService {

    @Autowired
    MongoTemplate mongoTemplate;
    @Autowired
    MongoPageHelper pageHelper;

    /**
     * 多条件 or  mobile id createTimeLong
     * @param
     * @return
     * @throws
     * @author zhuyanpeng
     * @date 2019/10/22
     */
    public Dept findBySearch(String search){
        Criteria criteriaMobile = Criteria.where("mobile").is(search);
        Criteria criteriaSearch = Criteria.where("id").is(search);
        Criteria criteriaTimeLong = Criteria.where("createTimeLong").is(search);
        Criteria criteria = new Criteria().orOperator(criteriaSearch, criteriaMobile,criteriaTimeLong);
        Query query = new Query().addCriteria(criteria);
        // 转为 BSON 等同于
        Bson mobileQueryBson = Filters.eq("mobile", search);
        Bson idQueryBson = Filters.eq("id", search);
        Bson createTimeLongQueryBson = Filters.eq("createTimeLong", search);
        Bson queryBson = Filters.or(mobileQueryBson, idQueryBson, createTimeLongQueryBson);
        MongoCollection<Document> collection = mongoTemplate.getCollection(Objects.requireNonNull(TableUtils.getTableName(Dept.class)));
        FindIterable<Document> documents = collection.find(queryBson);
        return  mongoTemplate.findOne(query, Dept.class);
    }

    /**
     * 返回指定的字段
     */
    public PageResult<Dept> querySimplePage(String name, Integer pageNum, Integer pageSize){
        Bson queryName = Filters.regex("name", ".*" + name + ".*");
        //回显的字段
        Document selectDocument = BeanUtils.buildDocument(Dept.class, false, true, true);
        return pageHelper.pageQuery(queryName, Dept.class, pageNum, pageSize,selectDocument);
    }

    /**
     *  相当于  db.getCollection('dept_info').find({"salary":{"$gte":startSalary},"salary":{"$lte":endSalary}})
     * @param startSalary
     * @param endSalary
     * @return List<Dept>
     */
    public List<Dept> queryBySalary(BigDecimal startSalary,BigDecimal endSalary){
        MongoCollection<Document> collection = mongoTemplate.getCollection(Objects.requireNonNull(TableUtils.getTableName(Dept.class)));
        //  >= startSalary
        Bson startSalaryBson = Filters.gte("salary", startSalary.doubleValue()*1000);
        // <= endSalary
        Bson endSalaryBson = Filters.lte("salary", endSalary.doubleValue()*1000);
        Bson queryBson = Filters.and(startSalaryBson, endSalaryBson);
        FindIterable<Document> documents = collection.find(queryBson);
        return   BeanUtils.copyList(documents,Dept.class);
    }

    /**
     *  相当于  db.getCollection('dept_info').find({"salary":{"$gte":startSalary},"salary":{"$lte":endSalary}}).skip(pageSize*pageNum).limit(pageNum)
     * @param startSalary
     * @param endSalary
     * @return List<Dept>
     */
    public PageResult<Dept> queryPageSalary(BigDecimal startSalary, BigDecimal endSalary, Integer pageNum, Integer pageSize) {
        //  >= startSalary
        Bson startSalaryBson = Filters.gte("salary", startSalary.doubleValue()*1000);
        // <= endSalary
        Bson endSalaryBson = Filters.lte("salary", endSalary.doubleValue()*1000);
        Bson queryBson = Filters.and(startSalaryBson, endSalaryBson);
        return  pageHelper.pageQuery(queryBson, Dept.class, pageNum, pageSize);
    }


    // 等同于 db.getCollection('dept_info').find({"$or":[{"name":/.*136.*/},{"mobile": /136.*/},{"sex":"136"}]})
    /**
     * 根据 名称 OR 电话 OR 性别 做模糊检索
     * 相当于
     * @param search 查询条件
     * @author zhuyanpeng
     * @date 2019/10/31
     */
    public PageResult<Dept> queryPage(String search, Integer pageNum, Integer pageSize) {
        Bson queryBson = new BsonDocument();
        if (StringUtils.isNotBlank(search)) {
            // 前后模糊 等同于 like %search%
            Bson  likeName = Filters.regex("name", ".*" + search + ".*");
            //  后模糊 等同于 like search%
            Bson likeMobile = Filters.regex("mobile",  search + ".*");
            // 等同于  ==
            Bson eqSex = Filters.eq("sex", search);
            // 使用 or 将三者拼接
            queryBson = Filters.or(likeMobile, likeName, eqSex);
        }
        return  pageHelper.pageQuery(queryBson, Dept.class, pageNum, pageSize);
    }


    // 等同于 db.getCollection('dept_info').remove({name:"name"})
    /**
     * 根据名称去删除数据 返回被删除的数据的id
     * @param
     * @return 
     * @throws 
     * @author zhuyanpeng
     * @date 2019/11/1
     */
    public String removeByName(String name){
        Bson queryBson = Filters.eq("name", name);
        MongoCollection<Document> collection = mongoTemplate.getCollection(Objects.requireNonNull(TableUtils.getTableName(Dept.class)));
        FindIterable<Document> documents = collection.find(queryBson);
        List<Dept> deptList = BeanUtils.copyList(documents, Dept.class);
        collection.deleteMany(queryBson);
        return deptList.get(0).getId();
    }

    /**
     * 根据id去修改其他信息 注意需要加上 $set 等同于: update table set ... where id = $search$
     * mongo bson :db.getCollection('dept_info').update({"_id":"1572570469058571910510215403"},{
     *     "$set" : {....}
     * @param
     * @return
     * @throws
     * @author zhuyanpeng
     * @date 2019/11/6
     */
    public void changeDeptById(Dept dept){
        MongoCollection<Document> collection = mongoTemplate.getCollection(Objects.requireNonNull(TableUtils.getTableName(Dept.class)));
        Bson mongoIdSearch = Filters.eq("_id", dept.getId());
        dept.setId(null);
        HashMap<String, Object> changeMap = new HashMap<>(1);
        changeMap.put("$set",dept);
        BsonDocument update = BsonDocument.parse(JSONObject.toJSONString(changeMap));
        collection.updateMany(mongoIdSearch,update);
    }
}
